<template>
  <div class="gantt" ref="gantt" :style="{ height: height }"></div>
</template>

<script>
/** mixin */
import { mixin_gantt } from '@ticui/mixins/mixin_gantt'
import Vue from 'vue'
import GanttDropdown from '@/components/common/GanttDropdown'
/** 工具 */
import { gantt } from 'processit-dhtmlx-gantt'
import { formatDate } from '@tapui/utils/date'
import { GANTT_ITEM_TYPE, MPM_PROJECT_ABNORMAL_STATE, MPM_PROJECT_STATE, MPM_MILEPOST_STATE, MPM_TASK_STATE } from '@/const/const'
import { validateNull } from '@tapui/utils/validate'

export default {
  mixins: [mixin_gantt],
  name: 'progressGanttComponent',
  data() {
    return {
      addGantt: {
        config: {
          readonly: true // 只读
        }
      },
      // 进度子节点类型
      progressTypeMap: {
        [GANTT_ITEM_TYPE.project]: {
          label: '项目',
          text: 'text',
          start_date: 'start_date',
          end_date: 'end_date'
        },
        [GANTT_ITEM_TYPE.milestone]: {
          label: '里程碑及任务',
          text: 'text',
          start_date: '',
          end_date: 'end_date'
        },
        [GANTT_ITEM_TYPE.task]: {
          label: '任务',
          text: 'text',
          start_date: 'start_date',
          end_date: 'end_date'
        }
      },
      // 时间轴类型
      scalesTypeMap: {
        year: [{ unit: 'year', step: 1, format: '%Y' }],
        month: [{ unit: 'year', step: 1, format: '%Y' }, { unit: 'month', step: 1, format: '%m' }],
        week: [{ unit: 'year', step: 1, format: '%Y' }, { unit: 'week', step: 1, format: '%w' }],
        day: [{ unit: 'month', step: 1, format: '%Y-%m' }, { unit: 'day', step: 1, format: '%d' }]
      }
    }
  },
  props: {
    height: {
      type: String,
      default: '600px'
    },
    // 甘特图数据
    taskData: {
      type: Object,
      default: () => ({
        data: [],
        links: []
      })
    },
    // 时间轴类型，年、月、日三种
    scalesType: {
      type: String,
      default: 'week'
    },
    // 展示字段
    showFields: {
      type: Array,
      default: () => {
        return ['text', 'start_date', 'end_date', 'update_date', 'schedule', 'disp_state', 'more']
      }
    }
  },
  watch: {
    // 时间轴变化
    scalesType(val) {
      gantt.config.scales = this.scalesTypeMap[val]
      if (this.$tap.validate.validateNull(this.taskData)) {
        return
      }
      gantt.init(this.$refs.gantt)
      this.setDragPositionByDate()
    }
  },
  computed: {
    isPM() {
      if (this.$store.getters.projectroles) {
        return this.$store.getters.projectroles.indexOf('pm') > -1
      } else {
        return false
      }
    }
  },
  methods: {
    /** 初始化 */
    drawerGantt() {
      this.initGantt(this.taskData)
    },
    addInitEvent() {
      // 修改任务树中的显示内容
      this.initColumns()
      // 添加任务超期类型
      this.initOverTask()
      // 修改样式
      this.changeClassName()
      // 修改时间轴类型
      gantt.config.scales = this.scalesTypeMap[this.scalesType]
      // 单击触发事件
      gantt.attachEvent('onTaskClick', (id, event) => {
        // 点击图标时不触发事件
        if (!event.srcElement.classList.contains('gantt_tree_icon')) {
          this.$emit('onTaskClick', id, event)
        }
        return true
      })
    },
    /** 根据进度类型初始化任务树 */
    initColumns() {
      let allColumns = [
        {
          name: 'text',
          label: '名称',
          width: 250,
          tree: true,
          resize: true,
          template: (obj) => `<span class="tooltip-title">${this.progressTypeMap[obj.type].label}：${obj.text}</span>`
        },
        {
          name: 'start_date',
          label: '开始时间',
          width: 100,
          resize: true,
          template: (obj) => obj[this.getResetField(obj.type, 'start_date')]
        },
        {
          name: 'end_date',
          label: '结束时间',
          width: 100,
          resize: true,
          template: (obj) => {
            let endDate = new Date(obj[this.getResetField(obj.type, 'end_date')])
            endDate.setDate(endDate.getDate() - 1)
            return endDate
          }
        },
        {
          name: 'more',
          label: '更多',
          width: 100,
          template: () => {
            return `<div class="more"></div>`
          },
          onrender: (obj, el) => {
            if (obj.type === 'mpmTask') {
              const content = el.querySelector('.more')
              new Vue({
                store: this.$store,
                render: (h) =>
                  h(GanttDropdown, {
                    props: { row: obj }
                  })
              }).$mount(content)
            }
          },
          hide: !this.isPM
        }
      ]
      gantt.config.columns = allColumns.filter(item => this.showFields.indexOf(item.name) > -1)
    },
    /** 根据类型获取显示的field */
    getResetField(type, field) {
      return this.progressTypeMap[type][field]
    },
    /** 开启鼠标移上任务条后弹出提示语功能 */
    openTooltip() {
      // 打开提示功能
      gantt.plugins({ tooltip: true })
      // 提示内容
      gantt.templates.tooltip_text = (start, end, task) => {
        const tooltipText = `<b>${this.progressTypeMap[task.type].label}：</b>${task.text}`
        const startDateStr = `<br/><b>开始日期:</b>${formatDate(task.start_date, 'yyyy-MM-dd')}`
        let endDate = new Date(task.end_date)
        endDate.setDate(endDate.getDate() - 1)
        const endDateStr = `<br/><b>结束日期:</b>${formatDate(endDate, 'yyyy-MM-dd')}`
        const planStartDateStr = `<br/><b>计划开始日期:</b>${task.plan_start_date}`
        const planEndDateStr = `<br/><b>计划结束日期:</b>${task.plan_end_date}`
        const taskdetail = `<br/><b>任务内容:</b>${task.task_detail}`
        const improveplan = `<br/><b>客户关系改善计划:</b>${task.improve_plan}`
        const taskfeedbackdetail = `<br/><b>任务反馈内容:</b>${task.task_feed_back_detail}`
        const submitdate = `<br/><b>任务反馈时间:</b>${task.submit_date}`
        const taskfeedbackschedule = `<br/><b>任务进度:</b>${task.task_feed_back_schedule}%`
        // 根据类型选择显示内容
        switch (task.type) {
          case GANTT_ITEM_TYPE.project:
            return `${tooltipText}
            ${[MPM_PROJECT_STATE.close, MPM_PROJECT_STATE.abnormalClose, MPM_PROJECT_STATE.review].includes(task.project_state) ? endDateStr : ''}
            ${planStartDateStr}
            ${planEndDateStr}`
          case GANTT_ITEM_TYPE.milestone:
            return `${tooltipText}
            ${task.mile_state >= MPM_MILEPOST_STATE.complete ? endDateStr : ''}
            ${planEndDateStr}`
          case GANTT_ITEM_TYPE.task:
            let responserDateStr = ''
            if (task.responsiblename) {
              responserDateStr = `<br/><b>责任人:</b>${task.responsiblename}`
            }
            return `${tooltipText}
            ${validateNull(task.task_detail) ? '' : taskdetail}
            ${responserDateStr}
            ${validateNull(task.improve_plan) ? '' : improveplan}
            ${validateNull(task.task_feed_back_detail) ? '' : taskfeedbackdetail}
            ${validateNull(task.task_feed_back_schedule) ? '' : taskfeedbackschedule}
            ${validateNull(task.submit_date) ? '' : submitdate}`
        }
      }
    },
    /** 修改样式 */
    changeClassName() {
      gantt.templates.task_class = (start, end, task) => {
        const classMap = {
          ganntproject: task.type === GANTT_ITEM_TYPE.project,
          over_project: task.type === GANTT_ITEM_TYPE.project && task.abnormalState === MPM_PROJECT_ABNORMAL_STATE.overdueProject,
          over_milepost: (task.type === GANTT_ITEM_TYPE.project && task.abnormalState === MPM_PROJECT_ABNORMAL_STATE.overdueMilepost) || (GANTT_ITEM_TYPE.milestone && task.isOverdue),
          overdue_task: (task.type === GANTT_ITEM_TYPE.project && task.abnormalState === MPM_PROJECT_ABNORMAL_STATE.overdueTask) || (task.type === GANTT_ITEM_TYPE.task && task.isOverdue),
          normalMilepost: task.type === GANTT_ITEM_TYPE.milestone && !task.isOverdue
        }
        return Object.keys(classMap).find((key) => classMap[key]) || 'normal'
      }
    },
    /** 新增超期任务类型 */
    initOverTask() {
      gantt.config.types.overdueTask = 'overdue_task'
      gantt.locale.labels.section_title = 'Subject'
      gantt.locale.labels.section_details = 'Details'
      gantt.locale.labels.type_overdueTask = 'OverdueTask'
      gantt.config.lightbox.overdueTask_sections = [{ name: 'title', height: 20, map_to: 'text', type: 'textarea', focus: true }, { name: 'details', height: 70, map_to: 'details', type: 'textarea' }, { name: 'type', type: 'typeselect', map_to: 'type' }, { name: 'time', height: 72, type: 'time', map_to: 'auto' }]
      gantt.templates.task_text = (start, end, task) => {
        if (task.type === gantt.config.types.overdueTask) {
          return `<b class="tooltip-title">${task.text}</b>`
        }
        return `<span class="tooltip-title">${task.text}</span>`
      }
    },
    /** 重写全部展开，全部折叠 */
    unfold() {
      this.isFold = !this.isFold
      if (this.isFold) {
        this.taskData.data.forEach((task) => {
          if ('mpmProject' !== task.type) {
            task.$open = false
          }
        })
      } else {
        this.taskData.data.forEach((task) => {
          task.$open = true
        })
      }
      gantt.init(this.$refs.gantt)
      this.$emit('refreshFold', this.isFold)
    }
  }
}
</script>

<style lang="scss" scoped>
.gantt {
  /deep/ .gantt_layout_root {
    .tooltip-title {
      display: block;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .normal {
      background: rgba(0, 128, 0, 0.3) !important;
      border: 2px solid #bfc518;
      .gantt_task_progress {
        background: green;
      }
      .gantt_task_content {
        background: rgba(0, 128, 0, 0.3) !important;
        /* background: #6ba8e3 !important; */
        /* z-index: -1; */
      }
    }
    .over_project {
      border: 2px solid #bfc518;
      background-color: rgba(216, 10, 30, 0.3);
      .gantt_task_progress {
        // background: #d80a1e;
        background: green;
      }
      .gantt_task_content {
        color: #6ba8e3;
      }
    }
    .over_milepost {
      border: 2px solid #bfc518;
      color: black;
      background: rgba(255, 140, 46, 0.3);
      .gantt_task_progress {
        // background: #ff8c2e;
        background: #d80a1e;
      }
      .gantt_task_content {
        color: #6ba8e3;
      }
    }
    .overdue_task {
      border: 2px solid #bfc518;
      color: #6ba8e3;
      background: rgba(250, 210, 50, 0.3);
      .gantt_task_progress {
        // background: #fad232;
        background: #d80a1e;
      }
      .gantt_task_content {
        color: #6ba8e3;
      }
    }
    .normalMilepost {
      .gantt_task_content {
        background: green !important;
      }
    }
    .gantt_milestone {
      // background-color: #ff8c2e !important;
    }
  }
  /deep/ .dragMarkerDefault {
    width: 5px;
    cursor: pointer;
  }
}
</style>
